function myProxy(target, name) {
    return new Proxy(target, {
        get(target, propKey, receiver) {    // 拦截对象属性的读取，比如proxy.foo和proxy['foo']
            let temp = Reflect.get(target, propKey, receiver);
            console.log(`${name} -> get ${propKey} -> return ${temp}`);
            if (typeof temp === "object")
                return myProxy(temp, `${name} -> ${propKey}`)
            return temp;
        },
        set(target, propKey, value, receiver) {   // 拦截对象属性的设置，比如proxy.foo = v或proxy['foo'] = v，返回一个布尔值。
            let temp = Reflect.set(target, propKey, value, receiver);
            console.log(`${name} -> set ${propKey} -> value ${value}`);
            return temp;
        },
        has(target, propKey) {   // 拦截propKey in proxy的操作，返回一个布尔值。
            let temp = Reflect.has(target, propKey);
            console.log(`${name} -> has ${propKey} -> return ${temp}`);
            return temp;
        },
        deleteProperty(target, propKey) {    // 拦截delete proxy[propKey]的操作，返回一个布尔值。
            let temp = Reflect.deleteProperty(target, propKey);
            console.log(`${name} -> delete ${propKey} -> return ${temp}`);
            return temp;
        },
        ownKeys(target) {    // 拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环，返回一个数组。该方法返回目标对象所有自身的属性的属性名，而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
            let temp = Reflect.ownKeys(target);
            console.log(`${name} -> ownKeys -> return ${temp}`);
            return temp;
        },
        getOwnPropertyDescriptor(target, propKey) {  // 拦截Object.getOwnPropertyDescriptor(proxy, propKey)，返回属性的描述对象。
            let temp = Reflect.getOwnPropertyDescriptor(target, propKey);
            console.log(`${name} -> getOwnPropertyDescriptor ${propKey} -> return ${temp}`);
            return temp;
        },
        defineProperty(target, propKey, propDesc) {  // 拦截Object.defineProperty(proxy, propKey, propDesc）、Object.defineProperties(proxy, propDescs)，返回一个布尔值。
            let temp = Reflect.defineProperty(target, propKey, propDesc);
            console.log(`${name} -> defineProperty ${propKey} -> return ${temp}`);
            return temp;
        },
        preventExtensions(target) {  // 拦截Object.preventExtensions(proxy)，返回一个布尔值。
            let temp = Reflect.preventExtensions(target);
            console.log(`${name} -> preventExtensions -> return ${temp}`);
            return temp;
        },
        getPrototypeOf(target) { // 拦截Object.getPrototypeOf(proxy)，返回一个对象。
            let temp = Reflect.getPrototypeOf(target);
            console.log(`${name} -> getPrototypeOf -> return ${temp}`);
            return temp;
        },
        isExtensible(target) {   // 拦截Object.isExtensible(proxy)，返回一个布尔值。
            let temp = Reflect.isExtensible(target);
            console.log(`${name} -> isExtensible -> return ${temp}`);
            return temp;
        },
        setPrototypeOf(target, proto) {  // 拦截Object.setPrototypeOf(proxy, proto)，返回一个布尔值。如果目标对象是函数，那么还有两种额外操作可以拦截。
            let temp = Reflect.setPrototypeOf(target, proto);
            console.log(`${name} -> setPrototypeOf -> return ${temp}`);
            return temp;
        },
        apply(target, object, args) {    // 拦截 Proxy 实例作为函数调用的操作，比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
            let temp = Reflect.apply(target, object, args);
            console.log(`${name} -> apply -> return ${temp}`);
            return temp;
        },
        construct(target, args) {    // 拦截 Proxy 实例作为构造函数调用的操作，比如new proxy(...args)。
            let temp = Reflect.construct(target, args);
            console.log(`${name} -> construct -> return ${temp}`);
            return temp;
        },
    });
}

// 定义一个目标对象
const targetObject = {
    name: "Alice",
    age: 25,
    greet() {
        return `Hello, my name is ${this.name}`;
    }
};

// 创建一个代理对象
const proxyObject = myProxy(targetObject, "proxyObject");

// 访问属性
console.log(proxyObject.name); // 输出日志并返回 Alice
console.log(proxyObject.age);  // 输出日志并返回 25

// 调用方法
console.log(proxyObject.greet()); // 输出日志并返回 "Hello, my name is Alice"

// 设置属性
proxyObject.age = 26; // 输出日志

// 检查属性
console.log('name' in proxyObject); // 输出日志并返回 true

// 删除属性
delete proxyObject.age; // 输出日志

// 获取所有属性
console.log(Object.keys(proxyObject)); // 输出日志并返回 ["name"]

// 定义新属性
Object.defineProperty(proxyObject, 'city', {
    value: 'New York',
    writable: true,
    enumerable: true,
    configurable: true
}); // 输出日志

// 检查是否可扩展
console.log(Object.isExtensible(proxyObject)); // 输出日志并返回 true
console.log(Object.getOwnPropertyDescriptor(proxyObject, "city"));